package com.wss.lsl.test.driven.common.util;

/**
 * 数组abc转换成cba。
 * <p>
 * 部分移动参照{@link OneDimensionalVectorUtil}
 * </p>
 * 
 * @author sean
 *
 */
public class MoveAbcUtil {

	/**
	 * 循环移动法
	 * 
	 * @param chars
	 * @param a
	 * @param b
	 * @return
	 */
	public static char[] loopMove(char[] chars, int a, int b) {

		int length = chars.length;

		int begin = 0, i = a, n = length;
		loopMove(chars, begin, i, n);
		begin = 0;
		i = b - a;
		n = length - a;
		loopMove(chars, begin, i, n);

		return chars;
	}

	// 循环转换中间的一部分
	public static char[] loopMove(char[] chars, final int begin, final int i,
			final int n) {

		int count = 0;
		int subIndex = 0;
		int cursorIndex = 0;
		char t = chars[begin];
		while (true) {
			if (count == n) {
				break;
			}
			int index = ((++subIndex) * i + cursorIndex);

			if (index % n == cursorIndex) {
				chars[(index - i) % n + begin] = t;
				count++;
				subIndex = 0;
				cursorIndex++;
				t = chars[cursorIndex + begin];
			} else {
				chars[(index - i) % n + begin] = chars[index % n + begin];
				count++;
			}

		}

		return chars;
	}

	/**
	 * 递归移动向量
	 * 
	 * @param chars
	 * @param i
	 * @return
	 */
	public static char[] recursionMove(char[] chars, int a, int b) {
		final int length = chars.length;

		recursionMove2(chars, a, length);
		recursionMove2(chars, b - a, length - a);

		return chars;
	}

	public static char[] recursionMove2(char[] chars, int left, int n) {

		final int right = n - left;
		int count, begin, newLeft;
		if (left > right) {
			count = right;
			begin = left - right;
			newLeft = begin;
		} else {
			count = left;
			begin = 0;
			newLeft = left;
		}
		int end = begin + count;
		for (int i = begin; i < end; i++) {
			char t = chars[i];
			chars[i] = chars[i + right];
			chars[i + right] = t;
		}
		if (left == right) {
			return chars;
		}
		n = n - count;
		return recursionMove2(chars, newLeft, n);
	}

	/**
	 * 反转法移动abc-->cba
	 * 
	 * @param chars
	 * @param i
	 * @return
	 */
	public static char[] reversalMove(char[] chars, final int a, final int b) {
		final int length = chars.length;

		reversalArray(chars, 0, a);
		reversalArray(chars, a, b);
		reversalArray(chars, b, length);
		reversalArray(chars, 0, length);

		return chars;
	}

	private static char[] reversalArray(char[] array, int begin, int end) {

		char t;
		for (int i = begin, j = end - 1; i < j; i++, j--) {
			t = array[i];
			array[i] = array[j];
			array[j] = t;
		}
		return array;
	}
}
